/*
 * EZCP_Sim_Receive.c
 *
 *  Created on: Apr 18, 2011
 *      Author: Nidhanee
 */

#include "EZCP_Sim_Common.h"

name_attach_t *pst_nameattach_attach=NULL;
//Size in bytes of each Message ID
extern unsigned int MSG_DATA_LENGTHS [EZCP_NUM_OF_MSGS];

void *pf_Receiver()
{
	//Create channel to receive from App
	EZCP_Simu_CreateChannel();

	//Start receive and processing of messages
	EZCP_Simu_RecvOutgoingMsg();

	return NULL;
}


//Interface with the Application to receive messages
void EZCP_Simu_CreateChannel()
{
	//print ("%s: Attach Channel with Application\n",__func__);

	if (NULL == (pst_nameattach_attach = name_attach(NULL, EZCP_ATTACH_APP2SIMU, 0)))
	{
		err (-1,"%s: name_attach error", __func__);
	}

}

//Receive messages from Application
void EZCP_Simu_RecvOutgoingMsg()
{
	s32 si_RcvId,si_Ret;

	msg_header_t st_my_hdr;
	msg_data_buf_t buf_data;
	MsgBuffer MsgReceived;
	int Start_Parse = 0, Length_Parse = 0,Ret_Parse = 0,k = 0;

	if (NULL == pst_nameattach_attach)
	{
		err (-1,"EZCP service: channel not available for receiving simulation...");
	}

	while (1)
	{
		print ("%s: Waiting to receive Application data ...\n",__func__);
		si_RcvId = MsgReceive(pst_nameattach_attach->chid, &st_my_hdr, EZCP_HDR_LEN, NULL);
		if (-1 == si_RcvId )
		{/* Error condition, exit */
			err (-1,"%s: MsgReceive error",__func__);
		}

		if (0 == si_RcvId)
		{// pulse received
			if (_PULSE_CODE_DISCONNECT == st_my_hdr.code)
				break;
			continue;
		}

		/* name_open() from Application sends a connect message, must EOK this */
		if (_IO_CONNECT  == st_my_hdr.type)
		{
			//Acknowledge receipt of message
			MsgReply( si_RcvId, EOK, NULL, 0 );
			continue;
		}

		/* Some other QNX IO message was received; reject it */
		if (st_my_hdr.type > _IO_BASE && st_my_hdr.type <= _IO_MAX )
		{
			MsgError( si_RcvId, ENOSYS );
			continue;
		}

		/* A message (presumably ours) received, handle */
		//printf ("%s: Message Received from Application\n",__func__);
		si_Ret = MsgRead(si_RcvId, buf_data, st_my_hdr.subtype, sizeof(st_my_hdr));
		if (-1 == si_Ret)
		{/* Error condition, exit */
			err (-1,"%s: MsgRead error",__func__);
		}

		MsgReceived.MsgID = st_my_hdr.type ;
		MsgReceived.Length = st_my_hdr.subtype ;
		memcpy (MsgReceived.Data,buf_data,sizeof(msg_data_buf_t));
		//MsgReceived.Data [MsgReceived.Length] = '\0';

		//printf ("%s:Data Bufdata Rcd as Binary = %s \n",__func__,buf_data);
		//printf ("%s:Data Rcd as Binary = %s \n",__func__,MsgReceived.Data);
		//print ("%s: Message ID Receieved = %d\n",__func__,MsgReceived.MsgID);
		// TODO : Handle messages received appropriately based on MsgReceived.MsgID

		// **************** Message Processing *******************
		switch (MsgReceived.MsgID)
		{
		case 1://To Gantry Arm actuator
				//Check Up or Down
				printf("%s: MsgID 1 - To Gantry Arm actuator\n",__func__);

				Start_Parse = 4;
				Length_Parse = 1;
				Ret_Parse = ParseBits(MsgReceived.Data,Start_Parse,Length_Parse);
				print("ParseBits returned Value: %x\n",Ret_Parse);
				if (Ret_Parse)
				{
					print("%s: Gantry Arm Actuator - UP\n",__func__);
				}
				else
				{
					print("%s: Gantry Arm Actuator - DOWN\n",__func__);
				}

				break;
		case 5://To Antenna
				print("%s: MsgID 5 Cash deducted to Antenna \n",__func__);

				//Cash Deducted Value
				Start_Parse = 4;
				Length_Parse = 12;
				Ret_Parse = ParseBits (MsgReceived.Data,Start_Parse,Length_Parse);
				printf("%s: ParseBits returned Cash Deducted: %x\n",__func__,Ret_Parse);

				break;
		case 7://To cashcard reader
				print("%s: MsgID 7 Cash deducted to CC Reader \n",__func__);

				Start_Parse = 4;
				Length_Parse = 12;
				Ret_Parse = ParseBits (MsgReceived.Data,Start_Parse,Length_Parse);
				printf("%s: ParseBits returned Cash Deducted: %x\n",__func__,Ret_Parse);

				break;
		case 10://Display
				print("%s: MsgID 10 Message to Display \n",__func__);
				break;
		case 18://To Ticket dispenser

				for(k = 0; k < 9; k++)
					printf("%s: Gantry ID Byte %d - %x \n",__func__,k,MsgReceived.Data[k]);


				print("%s: MsgID 18 Details  to Ticket dispenser \n",__func__);
				Start_Parse = 1;
				Length_Parse = 3;
				Ret_Parse = ParseBits (MsgReceived.Data,Start_Parse,Length_Parse);
				printf("%s: ParseBits returned Gantry ID: %x\n",__func__,Ret_Parse);

				Start_Parse = 4;
				Length_Parse = 13;
				Ret_Parse = ParseBits (MsgReceived.Data,Start_Parse,Length_Parse);
				printf("%s: ParseBits returned IU: %x\n",__func__,Ret_Parse);

				break;
		case 13://To Attendant Support Panel
				printf("%s: MsgID 13 - From  Carpark Attendant\n",__func__);

				Start_Parse = 4;
				Length_Parse = 1;
				Ret_Parse = ParseBits(MsgReceived.Data,Start_Parse,Length_Parse);
				if (Ret_Parse)
				{
					print("%s: Authorized to exit\n",__func__);
				}
				else
				{
					print("%s: Unauthorized to exit\n",__func__);
				}

				break;
		}


		// **************** End Of Message Processing *******************

		MsgReply(si_RcvId, EOK, 0, 0);
		//break;
	}//end of while(1)

	/* Remove the name from the space */
	name_detach(pst_nameattach_attach, 0);
}

int ParseBits(msg_data_buf_t buf, int Start, int Length)
{
	int i = 0;
	long message_value = 0;
	int mask;
    int some = 0;
	for(i = 0; i < 4; i++)
	{
		some = pow((double)256,(double)i);
        message_value += buf[i] * some ;
	}

    //printf("message value: %x\n",message_value);

	message_value = message_value >> (Start-1);

	//printf("message value: %x\n",message_value);

	mask = pow((double)2,(double)Length)-1;
	//printf("mask: %x\n",mask);

	message_value = message_value & mask;
	//printf("message value: %x\n",message_value);

	return message_value;

}
